package com.zxl.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zxl.constants.ESConstants;
import com.zxl.service.ESService;
import com.zxl.vo.Goods;
import com.zxl.vo.Param;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @packageName com.zxl.service.impl
 * @ClassName
 * @Author zxl
 * @Description //TODO
 * @date
 **/
@Service
public class ESServiceImpl implements ESService {


    @Autowired
    private RestHighLevelClient highLevelClient;

    @Override
    public void add(Goods goods) throws Exception {
        IndexRequest request = new IndexRequest(ESConstants.GOODS_INDEX, ESConstants.GOODS_TYPE);
        request.source(JSON.toJSONString(goods), XContentType.JSON);

        IndexResponse index = highLevelClient.index(request, RequestOptions.DEFAULT);
    }

    @Override
    public void addAll(List<Goods> goods) throws Exception {


    }

    @Override
    public List<Goods> list(Param param) throws IOException {

        //获取request
        SearchRequest request = new SearchRequest(ESConstants.GOODS_INDEX);
        request.types(ESConstants.GOODS_TYPE);

        //查询条件（分词、高亮、排序）
        SearchSourceBuilder builder = new SearchSourceBuilder();
        if (param.getSort() != null) {
            switch (param.getSort()) {
                case 0:
                    builder.sort("id", SortOrder.ASC);
                    break;
                case 1:
                    builder.sort("gprice", SortOrder.DESC);
                    break;
                case 2:
                    builder.sort("typeid", SortOrder.DESC);
                    break;
            }
        }
        if (!StringUtils.isEmpty(param.getKeyWords())) {
            builder.query(QueryBuilders.multiMatchQuery(param.getKeyWords(), "gdesc", "gname"));
        }
        if (param.getTypeid() != null) {
            builder.query(QueryBuilders.termQuery("typeid", param.getTypeid()));
        }


        HighlightBuilder highlight = new HighlightBuilder();
        highlight.field("gdesc");
        highlight.field("gname");
        highlight.preTags("<font color='blue'>");
        highlight.postTags("</font>");
        highlight.fragmentSize(50);
        builder.highlighter(highlight);
        //执行查询
        request.source(builder);
        SearchResponse search = highLevelClient.search(request, RequestOptions.DEFAULT);
        //处理结果
        List<Goods> list = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            Map<String, Object> map = hit.getSourceAsMap();
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField gname = highlightFields.get("gname");
            HighlightField gdesc = highlightFields.get("gdesc");
            if (gname != null) {
                String s = gname.getFragments().toString();
                map.put("gname", s);
            }
            if (gdesc != null) {
                String s = gdesc.getFragments()[0].toString();
                map.put("gdesc", s);
            }
            Goods goods = JSON.parseObject(JSON.toJSONString(map), Goods.class);
            list.add(goods);
        }

        return list;
    }
}
